package com.winning.devops.batch.error.ch01;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

/**
 * 异常简单处理Job配置
 *
 * @author chensj
 * @date 2020-03-07 21:55
 */
@Configuration
public class ErrorDemoJobConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job errorDemoJob() {
        return jobBuilderFactory.get("errorDemoJob")
                // 第一次执行的时候，stepContext不包含chensj=true这个键值对，会报错，同时，会将chensj=true放到stepContext中
                // 第二次执行的时候，此时的stepContext包含chensj=true，会直接执行
                .start(errorDemoFirstStep())
                .next(errorDemoSecondStep())
                .build();
    }

    @Bean
    public Step errorDemoSecondStep() {
        return stepBuilderFactory.get("errorDemoSecondStep")
                .tasklet(errorHandling())
                .build();
    }

    @Bean
    public Step errorDemoFirstStep() {
        return stepBuilderFactory.get("errorDemoFirstStep")
                .tasklet(errorHandling())
                .build();
    }

    @Bean
    public Tasklet errorHandling() {

        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                Map<String, Object> stepExecutionContext = chunkContext.getStepContext().getStepExecutionContext();
                // 判断step 执行的上下文中是否包含key=chensj
                if (stepExecutionContext.containsKey("chensj")) {
                    System.out.println(chunkContext.getStepContext().getStepName() + "The second run execute success");
                    return RepeatStatus.FINISHED;
                } else {
                    System.out.println(chunkContext.getStepContext().getStepName() + "The first run execute fail");
                    chunkContext.getStepContext().getStepExecution().getExecutionContext().put("chensj", true);
                    throw new RuntimeException("Error ....");
                }
            }
        };
    }
}
